import axios from 'axios';

import ZwMessage from './message';
import storage from './storage';

const httpStatusMessage = {
    200: '服务器成功返回请求的数据',
    201: '新建或修改数据成功。',
    202: '一个请求已经进入后台排队（异步任务）',
    204: '删除数据成功。',
    400: '发出的请求有错误，服务器没有进行新建或修改数据的操作。',
    401: '用户没有权限（令牌、用户名、密码错误）。',
    403: '用户得到授权，但是访问是被禁止的。',
    404: '发出的请求针对的是不存在的记录，服务器没有进行操作',
    406: '请求的格式不可得。',
    410: '请求的资源被永久删除，且不会再得到的。',
    422: '当创建一个对象时，发生一个验证错误。',
    500: '服务器发生错误，请检查服务器',
    502: '网关错误',
    503: '服务不可用，服务器暂时过载或维护',
    504: '网关超时'
};

let isRefreshing = false;

const CancelToken = axios.CancelToken;

let cancelRequest: any = '';

/**
 * 请求拦截器
 */
const sCrmAxios = axios.create({
    headers: {
        'X-Requested-With': 'XMLHttpRequest',
        'Content-Type': 'application/json'
    }
});

sCrmAxios.interceptors.request.use(
    function (config: any) {
        config.timeout = 60000;
        const stateInfo: any = storage.get('zw-scrm-state') || {};
        const token = stateInfo?.user?.userInfo?.loginToken || '';
        if (token) {
            config.headers['auth-token'] = token;
        }
        if (config.type === 0) {
            config.withCredentials = true;
        }
        if (config.type === 2) {
            config.headers['Content-Type'] = 'multipart/form-data;';
            if (config.oss) {
                delete config.headers['auth-token'];
            }
        }
        return config;
    },
    function (error) {
        return Promise.reject(error);
    }
);

const sCrmRequest = (options = {}) => {
    const {
        url,
        method = 'post',
        type,
        headers = {
            'content-type': 'application/json'
        },
        responseType,
        params,
        data,
        errMsg
    }: any = options;

    const item = {
        url,
        type,
        headers,
        method,
        params,
        data,
        responseType,
        errMsg,
        cancelToken: new CancelToken((c: any) => {
            cancelRequest = c;
        })
    };
    return new Promise((resolve, reject) => {
        sCrmAxios(item)
            .then(resp => {
                successHandler(resp, resolve, reject);
            })
            .catch(err => {
                errorHandler(err.response, reject);
            });
    });
};

/**
 * 接口处理
 * @param resp
 * @param resolve
 */
function successHandler(resp, resolve, reject) {
    if (resp.request.responseType === 'arraybuffer') {
        resolve(resp);
    } else {
        const statusMsg = httpStatusMessage[resp.status];
        // 请求阿里云返回参数
        if (resp.config.type === 1) {
            return resolve(resp.data);
        }
        if (resp.status >= 200 && resp.status < 300) {
            const code = resp.data.code || resp.data.status || 0;
            if (code === 200 || code === 0) {
                return resolve(resp.data.data || resp.data.result);
            } else if ([401, 406].includes(code)) {
                if (!isRefreshing) {
                    isRefreshing = true;
                    ZwMessage.error('用户登录已过期，请重新登录');
                }
                location.href = '/login';
                return reject(resp.data);
            } else {
                if (resp.config.errMsg) {
                    ZwMessage.error(resp.data.msg || '系统繁忙，请稍后再试');
                }
                return reject(resp.data.msg);
            }
        } else {
            ZwMessage.error(statusMsg);
        }
    }
}

/**
 * 错误接口处理
 * @param error
 * @param reject
 */
function errorHandler(resp, reject) {
    if (resp && resp.data) {
        const message = `${resp.data?.message || resp.data?.msg || '系统异常'}`;
        ZwMessage.error(message);
    }
    reject && reject();
}

export { cancelRequest };
export default sCrmRequest;
